package cn.darkhorse.workflow.service.impl;

import cn.darkhorse.api.IActivitiService;
import cn.darkhorse.exception.InteractionFailedException;
import cn.darkhorse.workflow.auto.entity.*;
import cn.darkhorse.workflow.auto.service.*;
import cn.darkhorse.workflow.dao.BpmnSysDeptDao;
import cn.darkhorse.workflow.service.ISysUserAndPostExtService;
import cn.darkhorse.workflow.tool.WorkflowConstants;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.activiti.engine.IdentityService;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author: mr.wang
 * @time: 2021/4/16 9:41
 */
@Service
public class SysUserAndPostExtServiceImpl implements ISysUserAndPostExtService{
	
	@Resource
	private IBpmnSysUserService sysUserService;
	@Resource
	private IBpmnSysPostService sysPostService;
	@Resource
	private IBpmnSysDeptService sysDeptService;
	@Resource
	private IBpmnSysUserPostService sysUserPostService;
	@Resource
	private IActivitiService activitiService;
	@Autowired
	IBpmnWorkflowService iBpmnWorkflowService;
	@Autowired
	IBpmnTaskService iBpmnTaskService;
	@Autowired
	private BpmnSysDeptDao bpmnSysDeptDao;

	@Transactional
	@Override
	public void addBpmnSysUser(BpmnSysUser user) {
		boolean b = sysUserService.saveOrUpdate(user);
		//流程添加用户
		activitiService.createUser(user.getUserName());
		
	}
	
	@Override
	public void updateBpmnSysUser(BpmnSysUser user) {
		sysUserService.saveOrUpdate(user);
	}
	
	@Override
	public void deleteBpmnSysUser(String userName) {
		LambdaQueryWrapper<BpmnSysUser> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BpmnSysUser::getUserName,userName);
		sysUserService.remove(wrapper);
		activitiService.deleteUser(userName);
	}
	
	@Transactional
	@Override
	public void insertSyspost(BpmnSysPost sysPost) {
		sysPostService.saveOrUpdate(sysPost);
		//流程添加岗位
		activitiService.createGroup(sysPost.getPostCode(),sysPost.getPostName());
		
	}
	
	@Transactional(rollbackFor = RuntimeException.class)
	@Override
	public void updateSyspost(String postCode,BpmnSysPost sysPost) {
		boolean b = selectTaskAndWorkFlow(postCode);
		if(b){
			throw new InteractionFailedException("该岗位已建立流程！");
		}
		//流程添加岗位
		deleteSyspost(postCode);
		sysPost.setDeptId(null);
		sysPostService.save(sysPost);
		activitiService.createGroup(sysPost.getPostCode(),sysPost.getPostName());
		
	}
	
	/**
	 *
	 * @param postCode
	 */
	@Transactional
	@Override
	public void deleteSyspost(String postCode) {
		boolean b = selectTaskAndWorkFlow(postCode);
		if(b){
			throw new InteractionFailedException("该岗位已建立流程！");
		}
		LambdaQueryWrapper<BpmnSysPost> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BpmnSysPost::getPostCode,postCode);
		sysPostService.remove(wrapper);
		activitiService.deleteGroup(postCode);
	}
	
	
	
	
	
	@Transactional
	@Override
	public void insertSysAndpost(List<String> postCodes,String userName,String nickName,String phoneNumber,String status,Long deptId) {
		List<BpmnSysUserPost> userPosts = new ArrayList<>();
		BpmnSysUser sysUser = getUserIdByUserName(userName);
		Long userId = sysUser.getUserId();
		//获取用户所在的组
		List<String> groupIds = groupIdsByUserId(userName);
		//流程添加用户与岗位
		for(String code:postCodes){
			Long postId = getPostIdByPostCode(code);
			BpmnSysUserPost userPost = new BpmnSysUserPost();
			userPost.setUserId(userId)
					.setPostId(postId);
			userPosts.add(userPost);
			if(checkExists(code,userName)){
				activitiService.createMemberShip(userName,code);
			}
		}
		//删除用户与组关系
		if(groupIds != null &&groupIds.size()>0){
			 groupIds.removeAll(postCodes);
			if(groupIds != null &&groupIds.size()>0){
				for(String group:groupIds){
					activitiService.deleteMemberShip(userName,group);
				}
			}
		}
		//删除用户与岗位数据
		deleteUserAndPost(userId);
		//修改用户名称
		sysUser.setNickName(nickName).setPhonenumber(phoneNumber).setStatus(status).setDeptId(deptId);
		sysUserService.updateById(sysUser);
		sysUserPostService.saveBatch(userPosts);
	}
	
	@Override
	public void updateSysAndpost(List<String> postCodes,String userName) {
	
		
	}
	
	@Resource
	private IdentityService identityService;
	
	/**
	 * 校验是否用户与组已发布
	 * @param code
	 */
	private boolean checkExists(String code,String userName){
		List<User> users = identityService.createUserQuery().memberOfGroup(code).list();
		if(null != users&&users.size()>0){
			for(User user :users){
				if(user.getId().trim().equals(userName)){
					return false;
				}
			}
		}
		return true;
	}
	
	/**
	 * 获取用户所在的所有组
	 * @param userName
	 * @return
	 */
	private List<String> groupIdsByUserId(String userName){
		List<String> groupIds = new ArrayList<>();
		List<Group> groups = identityService.createGroupQuery().groupMember(userName).list();
		if(null != groups&&groups.size()>0){
			for(Group group :groups){
				groupIds.add(group.getId());
			}
		}
		return groupIds;
	}
	
	
	
	
	
	@Override
	public void insertSysDept(BpmnSysDept sysDept,Long relativeManager,Long relativeInCharge) {
		boolean b = sysDeptService.save(sysDept);
		if(!b){
			throw new InteractionFailedException("部门同步流程错误！");
		}
		if(1 == sysDept.getDeptType()){
			//保存相对岗位
			saveRelativePosition(sysDept.getDeptId(),relativeManager,relativeInCharge);
		}
		
	}
	
	@Override
	public void updateSysDept(BpmnSysDept sysDept,Long relativeManager,Long relativeInCharge) {
		BpmnSysDept newParentDept = getSysDeptById(sysDept.getParentId());
		BpmnSysDept oldDept = getSysDeptById(sysDept.getDeptId());
		if (null != newParentDept && null != oldDept)
		{
			String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getDeptId();
			String oldAncestors = oldDept.getAncestors();
			sysDept.setAncestors(newAncestors);
			updateDeptChildren(sysDept.getDeptId(), newAncestors, oldAncestors);
		}
		 bpmnSysDeptDao.updateDept(sysDept);
		if (WorkflowConstants.NORMAL.equals(sysDept.getStatus()))
		{
			// 如果该部门是启用状态，则启用该部门的所有上级部门
			updateParentDeptStatus(sysDept);
		}
		//修改相对岗位
		updateRelativePosition(sysDept.getDeptId(),relativeManager,relativeInCharge,sysDept.getDeptType());
	}
	
	@Override
	public void updateRePo(Long deptId, Long relativeManager, Long relativeInCharge,Integer deptType) {
		//修改相对岗位
		updateRelativePosition(deptId,relativeManager,relativeInCharge,deptType);
	}
	
	@Override
	public void deleteSysDept(Long deptId) {
			int i = bpmnSysDeptDao.deleteDeptById(deptId);
			if(i == 0){
				throw new InteractionFailedException("部门同步流程错误！");
				}
	}
	/**
	 * 删除用户
	 */
	private void deleteUserAndPost(Long userId){
		LambdaQueryWrapper<BpmnSysUserPost> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BpmnSysUserPost::getUserId,userId);
		boolean b = sysUserPostService.remove(wrapper);
	}
	
	/**
	 * 通过userName得到userId
	 */
	private BpmnSysUser getUserIdByUserName(String userName){
		LambdaQueryWrapper<BpmnSysUser> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BpmnSysUser::getUserName,userName)
				.eq(BpmnSysUser::getDelFlag,"0");
				//.eq(BpmnSysUser::getStatus,"0")
		BpmnSysUser user = sysUserService.getOne(wrapper);
		if(null == user){
			throw new InteractionFailedException("用户数据缺失！");
		}
		return user;
	}
	
	/**
	 * 通过userName得到userId
	 */
	private Long getPostIdByPostCode(String postCode){
		LambdaQueryWrapper<BpmnSysPost> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BpmnSysPost::getPostCode,postCode)
				.eq(BpmnSysPost::getIsDelete,"0")
				.eq(BpmnSysPost::getStatus,"0");
		BpmnSysPost post = sysPostService.getOne(wrapper);
		if(null == post){
			throw new InteractionFailedException("岗位数据缺失！");
		}
		return post.getPostId();
	}
	
	
	public boolean selectTaskAndWorkFlow(String post){
		if (post == null || "".equals(post) || " ".equals(post)){
			throw new RuntimeException ();
		}
		//查询未删除的工作流信息
		LambdaQueryWrapper<BpmnWorkflow> bpmnWorkflowWrapper = new LambdaQueryWrapper<BpmnWorkflow>()
				.eq(BpmnWorkflow::getIsDelete, WorkflowConstants.DELETE_FALSE);
		List<BpmnWorkflow> bpmnWorkflows = iBpmnWorkflowService.list(bpmnWorkflowWrapper);
		List<Long> workflowId = new ArrayList<>();
		if (bpmnWorkflows.size() > 0 && bpmnWorkflows != null){
			bpmnWorkflows.forEach(bpmnWorkflow -> {
				workflowId.add(bpmnWorkflow.getId());
			});
		}
		if(null == workflowId ||workflowId.size() == 0){
			return false;
		}
		//获取未删除的工作流的任务相关信息
		LambdaQueryWrapper<BpmnTask> bpmnTaskWrapper = new LambdaQueryWrapper<>();
		bpmnTaskWrapper.in(BpmnTask::getProcessId,workflowId);
		List<BpmnTask> bpmnTasks = iBpmnTaskService.list(bpmnTaskWrapper);
		if (bpmnTasks.size()>0 && null != bpmnTasks){
			for (BpmnTask bpmnTask: bpmnTasks){
				if (bpmnTask.getCandidatePost() != null && !"".equals(bpmnTask.getCandidatePost())){
					boolean b = checkPost(bpmnTask.getCandidatePost(),post);
					if (b){
						return true;
					}
				}
				if (bpmnTask.getSendPost() != null && !"".equals(bpmnTask.getSendPost())){
					boolean b = checkPost(bpmnTask.getSendPost(),post);
					if (b){
						return true;
					}
				}
			}
		}
		return false;
	}
	private boolean checkPost(String post,String lastPost){
		List<String> parse = JSONObject.parseArray(post,String.class);
		for (String name:parse){
			if (lastPost.equals(name)){
				return true;
			}
		}
		return false;
	}
	
	
	/**
	 * 修改子元素关系
	 *
	 * @param deptId 被修改的部门ID
	 * @param newAncestors 新的父ID集合
	 * @param oldAncestors 旧的父ID集合
	 */
	public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors)
	{
		List<BpmnSysDept> children = bpmnSysDeptDao.selectChildrenDeptById(deptId);
		for (BpmnSysDept child : children)
		{
			child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
		}
		if (children.size() > 0)
		{
			bpmnSysDeptDao.updateDeptChildren(children);
		}
	}
	
	/**
	 * 修改该部门的父级部门状态
	 *
	 * @param dept 当前部门
	 */
	private void updateParentDeptStatus(BpmnSysDept dept)
	{
		String updateBy = dept.getUpdateBy();
		dept = getSysDeptById(dept.getDeptId());
		dept.setUpdateBy(updateBy);
		sysDeptService.update(new LambdaUpdateWrapper<BpmnSysDept>().in(BpmnSysDept::getDeptId,dept.getAncestors())
								.set(BpmnSysDept::getStatus,dept.getStatus())
								.set(BpmnSysDept::getUpdateBy,dept.getUpdateBy()));
	}
	
	
	/**
	 * 通过ID获取部门信息
	 * @param deptId
	 * @return
	 */
	private BpmnSysDept getSysDeptById(Long deptId){
		LambdaQueryWrapper<BpmnSysDept> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(BpmnSysDept::getDeptId,deptId)
					.eq(BpmnSysDept::getDelFlag, WorkflowConstants.DELETE_FALSE);
		BpmnSysDept sysDept = sysDeptService.getOne(wrapper);
		return sysDept;
	}
	
	@Resource
	private IBpmnDeptRelativeService relativeService;
	
	/**
	 * 保存相对岗位信息
	 * @param deptId   部门Id
	 * @param relativeManager   部门经理
	 * @param relativeInCharge  分管领导
	 * @return
	 */
	private boolean saveRelativePosition(Long deptId,Long relativeManager,Long relativeInCharge){
			relativeManager = bpmnSysDeptDao.getBpmnUserIdBySysUserId(relativeManager);
			relativeInCharge = bpmnSysDeptDao.getBpmnUserIdBySysUserId(relativeInCharge);
			BpmnDeptRelative relative = new BpmnDeptRelative();
				relative.setDeptId(deptId).setRelativeManager(relativeManager).setRelativeInCharge(relativeInCharge);
			return relativeService.save(relative);
	}
	
	/**
	 * 修改相对岗位
	 * @param deptId
	 * @param relativeManager
	 * @param relativeInCharge
	 * @param deptType
	 * @return
	 */
	private boolean updateRelativePosition(Long deptId,Long relativeManager,Long relativeInCharge,Integer deptType){
		relativeManager = bpmnSysDeptDao.getBpmnUserIdBySysUserId(relativeManager);
		relativeInCharge = bpmnSysDeptDao.getBpmnUserIdBySysUserId(relativeInCharge);
		LambdaQueryWrapper<BpmnDeptRelative> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(BpmnDeptRelative::getDeptId,deptId);
		BpmnDeptRelative deptRelative = relativeService.getOne(wrapper);
		//新增
		if(null == deptRelative && 1 == deptType){
			BpmnDeptRelative relative = new BpmnDeptRelative();
			relative.setDeptId(deptId).setRelativeManager(relativeManager).setRelativeInCharge(relativeInCharge);
			return relativeService.save(relative);
		}
		//部门修改成公司
		if(null != deptRelative && 0 == deptType){
			relativeService.removeById(deptRelative.getId());
		}
		if(null == deptRelative && 0 == deptType){
			return true;
		}
		//修改
		deptRelative.setRelativeInCharge(relativeInCharge).setRelativeManager(relativeManager);
		return relativeService.updateById(deptRelative);
	}
	
	/**
	 * 用户停用--转办信息
	 * @param userNames
	 * @return
	 */
	@Override
	public List<BpmnSysUser> stopTransferUser(List<String> userNames) {
		LambdaQueryWrapper<BpmnSysUser> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.in(BpmnSysUser::getUserName,userNames)
					.eq(BpmnSysUser::getDelFlag, WorkflowConstants.NORMAL)
					.eq(BpmnSysUser::getStatus, WorkflowConstants.STOP);
		List<BpmnSysUser> userList = sysUserService.list(queryWrapper);
		return userList;
	}
	
	/**
	 * 用户停用--转办信息
	 * @param userNames
	 * @param type  0：停用、1：转办
	 * @return
	 */
	@Override
	public List<BpmnSysUser> stopTransferUser(List<String> userNames,Integer type) {
		LambdaQueryWrapper<BpmnSysUser> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(BpmnSysUser::getUserName,userNames)
				.eq(BpmnSysUser::getDelFlag, WorkflowConstants.NORMAL)
				.eq(BpmnSysUser::getStatus, WorkflowConstants.STOP);
		if(0== type){
			queryWrapper.isNull(BpmnSysUser::getHandoverPerson);
		}
		if(1== type){
			queryWrapper.isNotNull(BpmnSysUser::getHandoverPerson);
		}
		List<BpmnSysUser> userList = sysUserService.list(queryWrapper);
		return userList;
	}
	/**
	 * 用户停用--转办信息
	 * @param type  0：停用、1：转办
	 * @return
	 */
	@Override
	public List<BpmnSysUser> stopTransferUser(Integer type) {
		LambdaQueryWrapper<BpmnSysUser> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(BpmnSysUser::getDelFlag, WorkflowConstants.NORMAL)
				.eq(BpmnSysUser::getStatus, WorkflowConstants.STOP);
		if(0== type){
			queryWrapper.isNull(BpmnSysUser::getHandoverPerson);
		}
		if(1== type){
			queryWrapper.isNotNull(BpmnSysUser::getHandoverPerson);
		}
		List<BpmnSysUser> userList = sysUserService.list(queryWrapper);
		return userList;
	}


	/**
	 * 停用并设置交接人
	 * @param userName
	 * @param handoverPerson
	 * @param status
	 */
	@Override
	public void stopTransferUser(String userName,String status, String handoverPerson) {
		LambdaUpdateWrapper<BpmnSysUser> updateW = new LambdaUpdateWrapper<>();
		updateW.eq(BpmnSysUser::getUserName,userName)
				.eq(BpmnSysUser::getDelFlag, WorkflowConstants.DELETE_FALSE);
		if(StringUtils.isBlank(handoverPerson)){
			updateW.set(BpmnSysUser::getHandoverPerson,null);
		}else{
			updateW.set(BpmnSysUser::getHandoverPerson,handoverPerson);
		}
		if(StringUtils.isNotBlank(status)){
			updateW.set(BpmnSysUser::getStatus,status);
		}
		sysUserService.update(updateW);
	}
	
	/**
	 *
	 * @param userName
	 */
	@Override
	public String canBeHandoverPerson(String userName) {
		StringBuilder sb = new StringBuilder();
		LambdaUpdateWrapper<BpmnSysUser> updateW = new LambdaUpdateWrapper<>();
		updateW.eq(BpmnSysUser::getDelFlag, WorkflowConstants.DELETE_FALSE)
				.eq(BpmnSysUser::getHandoverPerson,userName);
		List<BpmnSysUser> userList = sysUserService.list(updateW);
		for(BpmnSysUser sysUser:userList){
			sb.append(sysUser.getUserName());
			sb.append("、");
		}
		if(StringUtils.isNotBlank(sb.toString()))
		{
			sb.delete(sb.toString().lastIndexOf("、"), sb.toString().length());
		}
		
		return sb.toString();
		
	}
	
	
	
}
